import React from 'react';
import { FieldProps, RJSFSchema } from '@rjsf/utils';
import { Flex, Input, InputNumber, Select } from 'antd';

/**
 * 有input和select的field，其中schema.properties必须包含一个值输入（value）和一个下拉选择（select）
 * 
 * 下拉选择项可以用enum或oneOf
 * @param {FieldProps} props
 * @returns {JSX.Element}
 * @example  
 * schema: {
      type: "object",
      title: "First height",
      properties: {
        v: { type: "number",default: 0.005 },
        s: {
          type: "string",
          default: 'Absolute',
          oneOf: [
            {
              const: "Absolute",
              title: "绝对"
            },
            {
              const: "Relative",
              title: "相对"
            }
          ]
        }
      }
    }
  * uiSchema: {
      'ui:filed': InputSelectField,
    }
 */
export const InputSelectField = ({
  formData,
  onChange,
  schema,
}: FieldProps<object>): JSX.Element => {
  const keys = Object.keys(schema.properties);
  if (keys?.length === 0) {
    throw new Error(
      'schema.properties 有且仅有两项，一个表示输入框，一个表示下拉选择框',
    );
  }
  let valueKey: string = undefined,
    selectKey: string = undefined;
  let options: RJSFSchema[] = undefined;
  for (const key of keys) {
    const property = schema.properties[key] as RJSFSchema;
    if (property?.oneOf) {
      selectKey = key;
      options = property?.oneOf as RJSFSchema[];
    } else if (property?.enum) {
      selectKey = key;
      options = property?.enum.map(
        (item) => ({ const: item, title: item }) as RJSFSchema,
      );
    } else {
      valueKey = key;
    }
  }
  // schema
  const valueSchema = schema.properties[valueKey] as RJSFSchema;
  const selectSchema = schema.properties[selectKey] as RJSFSchema;
  if (valueSchema == undefined) {
    throw new Error('schema.properties must contain value and select');
  }
  const valueType = valueSchema.type;
  let minValue: number = undefined;
  let maxValue: number = undefined;
  if (valueType === 'number') {
    minValue = valueSchema.exclusiveMinimum;
    // 实际最小值：如果是 exclusiveMinimum ，则加一点偏移
    minValue = minValue !== undefined ? minValue + 1e-10 : valueSchema.minimum;

    maxValue = valueSchema.exclusiveMaximum;
    // 实际最大值：如果是 exclusiveMaximum ，则减一点偏移
    maxValue = maxValue !== undefined ? maxValue - 1e-10 : valueSchema.maximum;
  }
  // 这样的赋值，有个问题：当用户删除全部（formData?.[key]为空），想重新填写时，会自动填上默认值
  const value = formData?.[valueKey] ?? valueSchema?.default;
  const select = formData?.[selectKey] ?? selectSchema?.default;

  const handleValueChange = (val: number | string | null) => {
    onChange({ [valueKey]: val, [selectKey]: select });
  };

  const handleSelectChange = (val: string) => {
    onChange({ [valueKey]: value, [selectKey]: val });
  };

  return (
    <Flex
      style={{ gap: 4 }}
      className='items-center'>
      <Flex
        style={{ flex: 1, gap: 10 }}
        className='items-center'>
        <span
          style={{ flex: 1 }}
          className='fs'>
          {schema.title}
        </span>
      </Flex>
      <Flex
        style={{
          width: 0,
          flex: 1,
          gap: 5,
          overflow: 'hidden',
          fontSize: 12,
        }}>
        {valueSchema.type === 'number' ? (
          <InputNumber
            value={value}
            min={minValue}
            max={maxValue}
            onChange={handleValueChange}
            style={{ flex: 1 }}
          />
        ) : (
          <Input
            value={value}
            onChange={(e) => handleValueChange(e.target.value)}
            style={{ flex: 1 }}
          />
        )}
        {options && (
          <Select
            style={{ width: '50%' }}
            styles={{ popup: { root: { borderRadius: '4px' } } }}
            value={select}
            onChange={handleSelectChange}
            options={options?.map((o) => ({ value: o.const, label: o.title }))}
          />
        )}
      </Flex>
    </Flex>
  );
};
